| 항목 | 내용 |
|---|
| 문서명 | Part 3: 암호화 키 수명주기 정책 |
| 제품명 | DTA Wide Sleep Management Platform |
| 작성일 | 2026-06-17 |
| 적용범위 | Part 3 (백엔드/인프라) |
| 관련 조항 | BSI TR-03161 O.Arch_3 (P.3-010), O.Cryp_4 |
| 참조 표준 | BSI TR-02102-1, BSI TR-02102-2, NIST SP 800-57 Part 1/2 |
1. 목적 및 범위
본 문서는 DTA Wide 백엔드 시스템에서 사용하는 모든 암호화 키 자료의 수명주기 정책을 정의한다. 정책은 난수 소스, 키 업무 분리(segregation of duties), 키/인증서 만료, 해싱을 통한 무결성 보증을 포함하며, 공인 표준 BSI TR-02102 및 NIST SP 800-57에 기반한다.
키 수명주기는 다음 6단계로 관리한다: 생성(Generation) → 보관(Storage) → 사용(Usage) → 교체(Rotation) → 백업(Backup) → 폐기(Destruction).
2. 사용 키 / 비밀값 카탈로그
2.1 백엔드 키
| Key ID | 용도 | 알고리즘 | 키 길이 / 비트 강도 | 저장 위치 | 교체 주기 |
|---|
CONSENT_HMAC_KEY | 동의 위변조 방지 HMAC 서명 | HMAC-SHA256 | 256-bit (min 32B) | GCP Secret Manager → Cloud Run env 주입 | 연 1회(수동) + 침해 시 즉시 |
AUTH_OAUTH_FBETA_EID_CLIENT_SECRET | fbeta eID OAuth2 client 인증 | Bearer secret | min 32B random | GCP Secret Manager → Cloud Run env 주입 | 연 1회 + fbeta 정책 |
EID_FBETA_JWKS_URL | fbeta IdP의 JWKS endpoint(URL) | n/a | n/a | GCP Secret Manager | 변경 시(fbeta 통지 후) |
JWT_SIGNING_KEY | 백엔드 access/refresh token 서명 | HS256 또는 RS256 | 256-bit / 2048-bit | GCP Secret Manager | 인프라 정책 |
2.2 클라이언트(모바일) 키
| Key ID | 용도 | 알고리즘 | 키 길이 | 저장 위치 | 교체 주기 |
|---|
| Native 2FA device key | ECC Challenge-Response 서명 | ECDSA P-256 | 256-bit (prime256v1) | iOS Secure Enclave / Android Keystore (비추출) | 사용자 reenroll 시 |
| AppCheck attestation key | iOS App Attest / Play Integrity | iOS: P-256 / Android: 키 기반 attestation | 256-bit (iOS) / 시스템 결정(Android) | iOS Secure Enclave / Android Keystore | OS 정책 |
| Email OTP code | 일회용 이메일 인증 코드 | random | 6자리 숫자 / 30분 TTL | 모바일 미저장 — 백엔드 Redis 캐시 only | n/a |
2.3 백엔드가 수신/저장하는 공개키
| Key ID | 용도 | 알고리즘 | 저장 형식 | 저장 위치 | 교체 주기 |
|---|
UserDeviceAuthentication.publicKeySpki | Native 2FA 검증 | ECC P-256 SPKI DER (base64url) | DB column | private.user_device_authentications.public_key_spki | 사용자 reenroll/change 시 |
| fbeta JWKS public keys | id_token 서명 검증 | RS256 / ES256 | JWK (JSON) | Memory cache (jose, 1h TTL) | fbeta JWKS rotation에 따름 |
EidLink.eidHash | eID 식별자 단방향 해시 (1:1 매칭/중복 연동 방지) | SHA-256 | hex string | private.eid_links.eid_hash (UNIQUE 컬럼) | 영구 (1:1 사용자 매칭) |
3. 키 수명주기 단계
3.1 생성 (Generation)
| Key | 생성 방법 | 난수 소스 | 무결성 보증 |
|---|
CONSENT_HMAC_KEY | GCP Secret Manager + openssl rand -base64 32 | OS CSPRNG (/dev/urandom) | SHA-256 fingerprint 별도 기록 |
AUTH_OAUTH_FBETA_EID_CLIENT_SECRET | fbeta 제공자가 발급 → Secret Manager 즉시 저장 | fbeta CSPRNG (외부 책임) | 발급 timestamp + version 기록 |
| Native 2FA device key | iOS SecKeyGeneratePair(Secure Enclave) / Android KeyPairGenerator(KeyStore) | OS CSPRNG | 보안 영역 생성 → 외부 노출 불가 |
| Session/OAuth state nonce | Node.js crypto.randomBytes(32) | OS CSPRNG | 1회용, TTL 5~10분 |
생성 권한:
- Secret Manager
roles/secretmanager.admin 보유자(인프라 운영자) only
- 일반 개발자는 read-only(
roles/secretmanager.secretAccessor)
3.2 보관 (Storage)
| Key | 보관 위치 | 접근 통제 |
|---|
| 백엔드 비밀값 | GCP Secret Manager (region: europe-west3) | IAM 기반, audit log 자동 기록 |
| 런타임 환경 변수 | Cloud Run 컨테이너 env (Secret Manager → env binding) | 컨테이너 메모리 only, 로그 출력 마스킹 |
| 모바일 키 | iOS Secure Enclave / Android Keystore | OS 강제 — 비추출(non-exportable) |
| 백엔드 공개키 | PostgreSQL DB column | Repository userId 필터 강제 |
비밀값은 소스 코드/리포지토리에 저장하지 않으며, Secret Manager에서 런타임 환경 변수로만 주입된다. 로그 출력 시 민감값은 마스킹 처리된다.
3.3 사용 (Usage) — 단일 목적 원칙 (O.Cryp_4)
| Key | 단일 목적 | 사용처 |
|---|
CONSENT_HMAC_KEY | 동의 HMAC 서명 전용 | ConsentHmacService.sign/verify only |
AUTH_OAUTH_FBETA_EID_CLIENT_SECRET | fbeta OAuth client auth 전용 | fbeta token endpoint 교환 only |
| Native 2FA device key | Challenge-Response 서명 검증 전용 | Native 2FA 서명 검증 서비스 only |
JWT_SIGNING_KEY | 세션 토큰 서명 전용 | 세션 발급 서비스 only |
각 키가 목적 외 용도로 사용되지 않도록 다음 통제를 적용한다:
- ConfigService namespace 분리로 키 접근 경로 격리
- 서비스 계층에서만 키 접근, Controller/Repository 직접 접근 금지
- TypeScript 강타입 + private 필드로 export 차단
3.4 교체 (Rotation)
| Key | 정책 |
|---|
CONSENT_HMAC_KEY | 수동(연 1회) + 침해 시 즉시. 자동 교체는 현재 미구현이며 KMS 격상 시 도입 검토(로드맵). |
| fbeta JWKS | 자동 — jose 라이브러리 1h cache, JWKS rotation 시 자동 갱신 |
| Native 2FA device key | 사용자 트리거 — reenroll / change 시 |
수동 교체 절차 (CONSENT_HMAC_KEY 예):
- Secret Manager 새 버전 추가
- Dual-key window(24h): 신규/구 키 모두 검증 가능하도록 배포
- 24h 후 구 키 서명분 검증 완료 확인
- 구 키 destroy
- Cloud Run env 갱신 (rolling deploy)
- 교체 audit log 기록
즉시 교체 트리거 (Compromise):
- 보안 사고 의심 시 즉시 destroy + 새 버전 생성
- 영향 받은 서명은 무효화 — 사용자 재인증 필요
- 내부 사고 보고 절차에 따라 기록
3.5 백업 (Backup)
| Key | 백업 메커니즘 |
|---|
| 백엔드 비밀값 | Secret Manager versioning — 모든 버전 보존, 롤백 가능 |
| Native 2FA device key | OS 보안 영역(Secure Enclave/Keystore) — 키 자체는 비추출, 사용자 reenroll로만 복구 |
| 공개키(DB) | PostgreSQL 정기 백업(동일 리전 multi-zone)에 포함 |
비밀값의 별도 평문 백업은 생성하지 않으며, Secret Manager versioning이 복구 수단을 제공한다.
3.6 폐기 (Destruction)
| Key | 폐기 사유 | 폐기 방법 | 폐기 검증 |
|---|
CONSENT_HMAC_KEY 구 버전 | 교체 완료 후 24h 경과 | Secret Manager version destroy | audit log + 콘솔 DESTROYED 상태 |
AUTH_OAUTH_FBETA_EID_CLIENT_SECRET | fbeta 계약 종료 또는 rotation | fbeta revoke + Secret Manager destroy | fbeta 통지 + audit log |
| Native 2FA device key | 사용자 reenroll, 앱 삭제, backup 만료 | OS 자동 삭제 + DB status = EXPIRED | cleanup 로그 |
| fbeta JWKS cache | 1h TTL 자동 만료 | jose 내부 자동 정리 | n/a |
폐기된 비밀값은 복구 불가하며, Secret Manager destroy는 영구 삭제이다.
4. 키 분리 (Segregation of Duties)
4.1 GCP IAM 역할 분리
| Role | 권한 | 부여 대상 |
|---|
roles/secretmanager.admin | 키 생성/교체/폐기 | 인프라 운영자(소수, 승인 절차) |
roles/secretmanager.secretAccessor | 런타임 키 read | dta-wide-api service account only |
roles/logging.viewer | Secret Manager audit log 조회 | 보안 감사 |
개발자는 운영 비밀값에 직접 접근하지 못한다. 로컬 개발은 dev/local 비밀값 또는 stub mode를 사용한다.
4.2 Audit Log
- 모든 Secret Manager 접근(read/write/destroy)은 Cloud Logging에 자동 기록
- 로그는 중앙 로깅 저장소(BigQuery)로 수집되어 소스 시스템에서의 삭제·조작에 대응
- 의심 행위 감지 시 알림
5. 무결성 보증 (Integrity Assurance)
| 메커니즘 | 적용 |
|---|
| 키 fingerprint (SHA-256) | 키 생성 시 별도 기록, 교체 시 비교 |
| Secret Manager versioning | 모든 변경 이력 자동 기록, 롤백 가능 |
| Audit log | 접근/변경 행위 Cloud Logging 기록 |
| Destroy 승인 절차 | 운영 비밀값 destroy는 승인 절차 적용 |
| 정기 점검 | Secret Manager 인벤토리 정기 검토 |
6. TR-02102-1 / NIST SP 800-57 적합성
| 키 / 알고리즘 | BSI TR-02102-1 | NIST SP 800-57 강도 | 적합성 |
|---|
| HMAC-SHA256 (256-bit) | §4.4.1 권장 | 128-bit 보안 | ✅ |
| ECDSA P-256 + SHA-256 | §4.3.3 권장 | 128-bit 보안 | ✅ |
| RSA 2048 (fbeta JWT) | §4.3.2 최소 2000-bit | 112-bit 보안 (2030년까지 유효) | ✅ |
| TLS 1.3 + AES-256-GCM | §3.3.1 권장 | 256-bit 보안 | ✅ |
| SHA-256 (단방향 해시) | §4.3 권장 | 128-bit collision resistance | ✅ |
모든 알고리즘이 TR-02102-1 권장 기준을 충족하며, 키 길이는 NIST 권장 보안 강도 이상이다.
6.1 알고리즘 Sunset Plan
- BSI/NIST 권장 기준 상향 시 본 문서를 갱신하고 마이그레이션 계획을 수립한다.
- 현재 알고리즘은 모두 2030년 이상 유효성을 보유한다.
7. 검토 주기
- 연 1회 정기 검토(다음: 2027-05)
- 침해 사고 발생 시 즉시 검토
- 외부 감사 피드백 반영 시 수시 갱신
8. 증빙 및 참조 (Artifacts)
- 키 카탈로그 (본 문서 Section 2)
- 수명주기 단계 정책 (Section 3 — 생성/보관/사용/교체/백업/폐기)
- IAM 역할 분리 매트릭스 (Section 4.1)
- 표준 적합성 매핑 (Section 6 — TR-02102-1 / NIST SP 800-57)
| 규정 | 요구사항 | 구현 | 증거 |
|---|
| BSI TR-03161 O.Arch_3 | 암호 키 수명주기 정책 문서화 | 본 정책(난수 소스/업무 분리/만료/무결성) | 본 문서 |
| BSI TR-03161 O.Cryp_4 | 키 단일 목적 사용 | Section 3.3 단일 목적 통제 | 본 문서 |
| BSI TR-02102 / NIST SP 800-57 | 공인 표준 기반 | Section 6 적합성 매핑 | 본 문서 |